#! /usr/bin/env python
# -*- coding: utf8 -*-

########################################################
# Part of MILIM NIRDAFOT project.
# Written by H. Magal, 2014
# See details on the project at the site:
#   https://sites.google.com/site/nirdafotdownloads/home
########################################################

import random
import pickle
import constants

# artificial lists' list used for debug
dbg_list = ((unicode ('אָלֶף', 'utf-8'),  unicode ('אַבְרָהָם', 'utf-8'), 1),
            (unicode ('בֵּית', 'utf-8'),  unicode ('בָּרוּך', 'utf-8'), 1),
            (unicode ('גִימֶל', 'utf-8'),  unicode ('גְּדַלְיָהוּ', 'utf-8'), 2),
            (unicode ('דָּלֶת', 'utf-8'),  unicode ('דָּוִד', 'utf-8'), 2),
            (unicode ('הֵא', 'utf-8'),   unicode ('הָגָר', 'utf-8'), 0),
            (unicode ('וָו', 'utf-8'),    unicode ('וֶרֶד', 'utf-8'), 0),
            (unicode ('זַיִן', 'utf-8'),   unicode ('זְרֻבָּבֶל', 'utf-8'), 0),
            (unicode ('חֵית', 'utf-8'),  unicode ('חֲנוֹך', 'utf-8'), 0),
            (unicode ('טית', 'utf-8'),  unicode ('טובה', 'utf-8'), 0),
            (unicode ('יוד', 'utf-8'),  unicode ('יונה', 'utf-8'), 0),
            (unicode ('כף', 'utf-8'),  unicode ('כרמית', 'utf-8'), 0),
            (unicode ('למד', 'utf-8'),  unicode ('לאה', 'utf-8'), 0))

class synonymDB ():
    def __init__ (self):
        try:                            # try reading the synonyms pickled file
            fout = open (constants.path_4_data_files + 'synonyms.data', 'rb')
            self.version = pickle.load (fout)
            self.db      = pickle.load (fout)
            if not constants.__DBversion__ is None:             # This is a debug mechanism. If the value here is not None, take it.
                self.version = constants.__DBversion__
            fout.close ()
            list_found = True
        except:
            list_found = False
        if not list_found:
            self.db = dbg_list
            self.version = '0.01'
        self.dbLen = len (self.db)
        self.first_time = True

    def getNewList (self, N):
        result = list()
        if self.first_time:
            self.first_time = False
            pair = (' ', ' ')
            for i in xrange(N):
                result.append (pair)
            return result                             # at first call return just spaces as the array of words

        intList = random.sample (xrange (self.dbLen), N) # form list of random N integers
        dont_coexist_list = list ()                   # form an empty list for next loop checks.

        # first step is to check the last number at each of the chosen tuples to see that there are no tuples
        # which shouldn't be displayed together (their 'coexist number' is identical)
        for i in xrange(N):
            tup = self.db [intList [i]]               # select the input tuple to check.
            coexist_number = int (tup [-1])           # get the last element, which the 'coexistNumber'
            if coexist_number != 0:                   # 0 means that this tuple can be seen without restrictions
                if coexist_number in dont_coexist_list: # if the number is already in the list, element[i] has to be replaced
                    intList.pop (i)
                    while True:
                        rint = random.randint (0, self.dbLen-1) # get random number
                        if not rint in intList:       # we have to check that number isn't already in the list
                            tup = self.db [rint]      # select the input tuple to check.
                            coexist_number = int (tup [-1]) # get the last element, which the 'coexistNumber'
                            if coexist_number == 0:   # to simplify program we select a tuple with number==0 (the majority of tuples have 0)
                                intList.insert (i, rint) # we replaced the 'bad' tuple
                                break                 # the while True loop
                else:                                 # else just add the number to the list for next passes
                    dont_coexist_list.append (coexist_number)

        # second step is the actual build of final list of pairs, after we took care not to show
        # pairs which shouldn't be seen together.
        for i in xrange(N):
            ilist = self.db [intList [i]]             # select the input list
            ilistr = list (ilist)                     # ilist is actually a tuple. we convert it into list
            ilistr.pop ()                             # remove last item from list, which is the 'don't coexist number'
            opair = random.sample (ilistr, 2)         # select random 2 items from input list
            result.append (opair)
        return result

    def getWholeList (self):
        return self.db

    def getListSize (self):
        return self.dbLen


def main ():
    constants.set_platform_dependent_vars ()
    hdb = synonymDB ()
    print '  DB version: ' + hdb.version
    print 'Groups count:', hdb.dbLen
    words = 0
    for e in hdb.db:
        words += (len (e) - 1)                      # last item in each list is the co-existance number, omit it.
    print ' Words count:', words


###### Main code ######
if __name__ == '__main__':
    main ()